<!doctype html>
<html>

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">

  <script src="../../webcomponentsjs/webcomponents-lite.js"></script>
  <script src="../../web-component-tester/browser.js"></script>
  <link rel="import" href="../../test-fixture/test-fixture.html">
  <link rel="import" href="helpers.html">

  <link rel="import" href="../../polymer/polymer-element.html">
  <link rel="import" href="../vaadin-grid-tree-toggle.html">
  <link rel="import" href="../vaadin-grid-tree-column.html">
  <link rel="import" href="../vaadin-grid.html">
</head>

<body>

  <test-fixture id="default">
    <template>
      <vaadin-grid-tree-toggle></vaadin-grid-tree-toggle>
    </template>
  </test-fixture>

  <test-fixture id="toggle-with-content">
    <template>
      <vaadin-grid-tree-toggle>
        <input><div>foo</div>
      </vaadin-grid-tree-toggle>
    </template>
  </test-fixture>

  <test-fixture id="column">
    <template>
      <vaadin-grid>
        <vaadin-grid-tree-column></vaadin-grid-tree-column>
      </vaadin-grid>
    </template>
  </test-fixture>

  <script>
    describe('tree toggle', () => {
      let toggle;

      function click(element) {
        const event = new CustomEvent('click', {
          bubbles: true,
          cancelable: true,
          composed: true
        });
        element.dispatchEvent(event);
        return event;
      }

      beforeEach(() => {
        toggle = fixture('default');
      });

      it('should have leaf false by default', () => {
        expect(toggle.leaf).to.not.be.ok;
      });

      it('should have expanded false by default', () => {
        expect(toggle.expanded).to.not.be.ok;
      });

      it('should not toggle on click if leaf', () => {
        toggle.leaf = true;

        const clickEvent = click(toggle);
        expect(toggle.expanded).to.not.be.ok;
        expect(clickEvent.defaultPrevented).to.be.false;
      });

      it('should toggle on click', () => {
        let clickEvent = click(toggle);
        expect(toggle.expanded).to.be.true;
        expect(clickEvent.defaultPrevented).to.be.true;

        clickEvent = click(toggle);
        expect(toggle.expanded).to.be.false;
        expect(clickEvent.defaultPrevented).to.be.true;
      });

      it('should not toggle on internal focusable click', () => {
        toggle = fixture('toggle-with-content');
        const clickEvent = click(toggle.querySelector('input'));
        expect(toggle.expanded).to.be.false;
        expect(clickEvent.defaultPrevented).to.be.false;
      });

      it('should toggle on internal non-focusable element click', () => {
        toggle = fixture('toggle-with-content');
        const clickEvent = click(toggle.querySelector('div'));
        expect(toggle.expanded).to.be.true;
        expect(clickEvent.defaultPrevented).to.be.true;
      });

      it('should notify for expanded on toggle', () => {
        const spy = sinon.spy();
        toggle.addEventListener('expanded-changed', spy);

        click(toggle);

        expect(spy.callCount).to.equal(1);

        toggle.removeEventListener('expanded-changed', spy);
      });

      it('should have default slot', () => {
        const slot = toggle.shadowRoot.querySelector('slot:not([name])');
        expect(slot).to.be.ok;
      });

      describe('level', () => {
        it('should have level zero by default', () => {
          expect(toggle.level).to.equal(0);
        });

        it('should have zero spacer width by default', () => {
          const spacer = toggle.shadowRoot.querySelector('#level-spacer');
          expect(spacer.getBoundingClientRect().width).to.equal(0);
        });

        it('should increase spacer width for each level step', () => {
          const spacer = toggle.shadowRoot.querySelector('#level-spacer');
          let prevWidth = 0;
          for (let i = 1; i < 3; i++) {
            toggle.level = i;
            toggle._debouncerUpdateLevel.flush();
            const width = spacer.getBoundingClientRect().width;
            expect(width).to.be.gt(prevWidth);
            prevWidth = width;
          }
        });
      });

      describe('themability', () => {
        it('should have shadow parts', () => {
          [
            'toggle'
          ].forEach(partName => {
            expect(toggle.shadowRoot.querySelector(`[part~="${partName}"]`)).to.not.be.null;
          });
        });
      });
    });

    describe('tree column', () => {
      let grid, column, toggle;

      beforeEach(() => {
        grid = fixture('column');
        column = grid.querySelector('vaadin-grid-tree-column');
        grid.dataProvider = (parmas, cb) => {
          cb([{name: 'foo', hasChildren: true}], 1);
        };
        flushGrid(grid);
        toggle = getBodyCellContent(grid, 0, 0).firstElementChild;
      });

      it('should be empty', () => {
        expect(toggle.textContent.trim()).to.be.empty;
      });

      it('should not be empty', () => {
        column.path = 'name';
        expect(toggle.textContent.trim()).to.equal('foo');
      });

      it('should be a leaf', () => {
        expect(toggle.leaf).to.be.true;
      });

      it('should not be a leaf', () => {
        column.itemHasChildrenPath = 'hasChildren';
        expect(toggle.leaf).to.be.false;
      });

    });
  </script>

</body>

</html>
